﻿/**********************************************************
*-----------------------------------*
* flareJ JavaScript Library
*-----------------------------------*
* 作者:Joe_Sky
* 邮箱:hitomi_doax@tom.com
* 最后更新时间:2010-12-28
*-----*-----*-----*-----*-----*-----*
* 基于jQuery
***********************************************************/

/*-------------------------*
* flareJ.Base
*-------*-------*
* 基础类库
*-------------------------*/
(function ($) {

    //#region flareJ
    this.flareJ = this.FJ = $.flareJ = $.FJ = function () {
        ///	<summary>
        /// flareJ Library
        ///	</summary>
    };
    //#endregion

    //#region 版本
    FJ.version = "0.0.1";
    //#endregion

    //#region FJ文件夹路径
    //根路径
    FJ.rootPath = "/JsLibrary/flareJ/";

    //设置
    (FJ.setRootPath = function (rootPath) {
        //根路径
        FJ.rootPath = rootPath;

        //图片文件夹
        FJ.imgPath = rootPath + "resources/image/";

        //css
        FJ.cssPath = rootPath + "resources/css/";

        //媒体文件
        FJ.media = rootPath + "resources/media/";

        //重新加载组件基类css
        //$(function(){
            var oSt = $("#ComponentJStyle");
            if (oSt.length > 0) oSt.remove();
            $("head").prepend('<link id="ComponentJStyle" href="' + FJ.cssPath + 'flareJ.Component.css" rel="stylesheet" type="text/css" />');
        //});
    })(FJ.rootPath);
    //#endregion

    //#region 类式继承模型

    /*-----------------------------------------------*
    * 修改自John Resig的Simple JavaScript Inheritance
    *------*-----*-----*-----*-----*-----*-----*-----*
    * 增加了可调用基类的所有成员
    *-----------------------------------------------*/

    //是否执行构造方法标记
    var initializing = false,
    //检测方法内是否包含某个字符串或对象名(先检测浏览器是否支持使用这种方式检测,否则不进行检测)
        fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/;

    //创建所有可继承对象的基类
    FJ.Class = function () {
        ///	<summary>
        /// 类式继承对象
        ///	</summary>
    };

    //继承方法
    FJ.Class.extend = function (prop) {
        ///	<summary>
        /// 类式继承方法
        ///	</summary>
        ///	<param name="prop" type="Object">
        ///	子类成员描述对象
        ///	</param>
        ///	<returns type="Function" />

        //保存基类原型的引用
        var _super = this.prototype;

        //实例化一个基类对象作为子类的原型,并且不执行构造方法
        initializing = true;
        var prototype = new this();
        initializing = false;

        //从子类成员描述对象中复制成员到子类原型中
        for (var name in prop) {
            //如果子类有基类的同名方法,则覆盖掉
            prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function"
            && fnTest.test(prop[name]) ?   //检测子类方法中是否含有_super方法
            (function (name, fn) {         //在执行每个子类方法时都会动态做一些引用的更新
                return function () {
                    this._base = _super;   //更新基类原型的引用
                    var tmp = this._super;

                    //将基类同名方法的引用保存在_super方法中
                    this._super = _super[name];

                    //执行完子类方法后由临时变量还原_super方法
                    var ret = fn.apply(this, arguments);
                    this._super = tmp;

                    return ret;
                };
            })(name, prop[name]) :
            (function (name, fn) {   //同上,只是没有调整_super方法
                return function () {
                    this._base = _super;
                    return fn.apply(this, arguments);
                }
            })(name, prop[name]);
        }

        //创建一个新的可继承的类
        function Class() {
            //执行构造方法
            if (!initializing && this.init)
                this.init.apply(this, arguments);
        }

        //将已经用子类成员描述对象覆盖过的基类对象保存在子类原型中
        Class.prototype = prototype;

        //指定子类的构造类
        Class.constructor = Class;

        //添加子类的继承方法
        Class.extend = arguments.callee;

        return Class;
    };
    //#endregion

    //#region 对象基类
    this.BaseJ = this.BJ = FJ.BaseJ = FJ.BJ = FJ.Class.extend({
        //#region 构造方法
        init: function (settings) {
            //参数
            this.settings = this.p = this.st = $.extend(true, {
                fjType: "BJ",
                objId: new Date().getTime(),    //元素ID
                evts: {},                       //事件
                eType: {}                       //实现执行子类事件时不会执行基类同名事件的标记,按每个事件名各写一个,值为当前类fjType
            }, settings);

            return this;
        },
        //#endregion

        //#region 初始化
        initFn: function () {
            //绑定自定义事件
            this.bindEvts();
        },
        //#endregion

        //#region 绑定自定义事件
        bindEvts: function () {
            for (var o in this.p.evts) {
                if (this.p.evts[o])
                    $(this).bind(o, this.p.evts[o]);
            }
        },
        //#endregion

        //#region 执行事件
        fire: function () {
            if (this.p.evts[arguments[0]]) {
                var arg = arguments, inxL = arg.length - 1;
                if (typeof arg[inxL] == "string" && arg[inxL].substr(arg[inxL].length - 1) == "J") {
                    if (this.p.eType[arg[0]] && this.p.eType[arg[0]] == arg[inxL]) //如果最后一个参数为fjType,则不执行基类的同名事件
                        return $(this).triggerHandler(arg[0], (function (a) {
                            if (typeof a == "object" || typeof a == "function")
                                return a;
                            else
                                return null;
                        })(arg[1]));
                }
                else {  //一定会执行的事件
                    return $(this).triggerHandler(arg[0], arg[1]);
                }
            }
        },
        //#endregion

        //#region 修改参数
        alterP: function (p) {
            this.p = $.extend(true, this.p, p);
        }
        //#endregion
    });
    //#endregion

    //#region 组件
    this.ComponentJ = this.CJ = FJ.ComponentJ = FJ.CJ = FJ.BJ.extend({
        //#region 构造方法
        init: function (elemObj, settings) {
            //参数
            this._super($.extend(true, {
                fjType: "CJ",
                obj: elemObj,                              //选择器选中的jquery对象
                selCondition: null,                        //选择器选中jquery对象的条件
                renderTo: "body",                         //要加载到的容器
                renderType: "append",                     //渲染方式
                widthF: 100,                               //最大宽度
                heightF: 100,                              //最大高度
                borderWidth: 1,                            //边框宽度
                style: null,                               //样式
                colorParams: {                             //颜色参数
                    borderOut: "#0f7cad",                  //外层边框
                    bgColor: "#F1F9FC"                     //背景色
                },
                evts: {                                    //事件
                    beforerender: function () { },          //渲染前
                    afterrender: function () { }            //渲染后
                },
                eType: (function (j) {
                    return {
                        beforerender: j,
                        afterrender: j
                    }
                })("CJ")
            }, settings));

            this.divOut = null;   //外层对象

            return this;
        },
        //#endregion

        //#region 初始化
        initFn: function () {
            this._super();

            //将参数字符串转化为jquery对象
            this.p.renderTo = (typeof this.p.renderTo == 'string' ? $(this.p.renderTo) : this.p.renderTo);

            //外层对象ID
            if (this.p.objId == null) {
                this.objId = "CJ_" + new Date().getTime();
            }
            else {
                this.objId = this.p.objId;
            }
        },
        //#endregion

        //#region 构建
        create: function () {
            this.fire("beforerender", "CJ");

            this.divOut = $('<div id="' + this.objId + '" style="display:none;border: ' + this.p.borderWidth + 'px solid ' + this.p.colorParams.borderOut + ';background-color:' + this.p.colorParams.bgColor + ';width:' + (typeof this.p.widthF == "number" ? this.p.widthF + 'px' : this.p.widthF) + ';height:' + (typeof this.p.heightF == "number" ? this.p.heightF + 'px' : this.p.heightF) + '"></div>')[this.p.renderType + "To"](this.p.renderTo);
            if (this.p.style != null) {
                this.divOut.attr("style", this.p.style);
            }

            this.fire("afterrender", "CJ");
            return this;
        },
        //#endregion

        //#region 显示
        show: function () {
            this.divOut.show();
            return this;
        },
        //#endregion

        //#region 隐藏
        hide: function () {
            if (this.divOut != null) {
                this.divOut.hide();
            }
        },
        //#endregion

        //#region 关闭
        close: function () {
            if (this.divOut != null) {
                this.divOut.hide();
            }
            this.divOut.remove();
        }
        //#endregion
    });

    //#region 绑定到jquery
    $.fn.extend({
        ComponentJ: function (settings) {
            return new FJ.ComponentJ(this, settings);
        },
        CJ: function (settings) {
            return $(this).ComponentJ(settings);
        }
    });
    //#endregion

    //#region 加载css
    $("head").append('<link id="ComponentJStyle" href="' + FJ.cssPath + 'flareJ.Component.css" rel="stylesheet" type="text/css" />');
    //#endregion
    //#endregion

    //#region 动画

    //#region 动画基类
    this.AnimateJ = this.AJ = FJ.AnimateJ = FJ.AJ = FJ.BJ.extend({
        //#region 构造方法
        init: function (elemObj, settings) {
            //参数
            this._super($.extend(true, {
                fjType: "AJ",
                speed: 500,
                sa: {
                    width: 100,
                    height: 100,
                    left: 100,
                    top: 100
                },
                cbP: function () { },
                cbS: function () { },
                cbC: function () { }
            }, settings));

            this.targetObj = elemObj;   //播放目标对象

            return this;
        },
        //#endregion

        //#region 播放
        go: function (state) { }
        //#endregion
    });
    //#endregion

    //#region 飞出
    this.AJ_fly = FJ.AJ_fly = FJ.AJ.extend({
        //#region 构造方法
        init: function (elemObj, settings) {
            //参数
            this._super(elemObj, $.extend(true, {
                fjType: "AJ_fly",
                speed: 500,
                sa: {
                    leftO: 100,
                    topO: 100
                }
            }, settings));

            return this;
        },
        //#endregion

        //#region 播放
        go: function (state) {
            var thiz = this;

            switch (state) {
                case "s":
                    this.targetObj.hide().css({
                        width: 0,
                        height: 0,
                        left: this.p.sa.leftO,
                        top: this.p.sa.topO
                    }).show().stop().animate({
                        width: this.p.sa.width,
                        height: this.p.sa.height,
                        left: this.p.sa.left,
                        top: this.p.sa.top
                    }, this.p.speed, function () {
                        thiz.p.cbS.call(thiz);
                    });
                    break;
                case "c":
                    this.targetObj.animate({
                        width: 0,
                        height: 0,
                        left: this.p.sa.leftO,
                        top: this.p.sa.topO
                    }, this.p.speed, function () {
                        thiz.targetObj.hide();
                        thiz.p.cbC.call(thiz);
                    });
                    break;
            }
        }
        //#endregion
    });
    //#endregion

    //#region 缓动
    this.AJ_easing = FJ.AJ_easing = FJ.AJ.extend({
        //#region 构造方法
        init: function (elemObj, settings) {
            //参数
            this._super(elemObj, $.extend(true, {
                fjType: "AJ_easing",
                speed: 500,
                speed2: 150,
                speed3: 70,
                opacity: 1
            }, settings));

            return this;
        },
        //#endregion

        //#region 播放
        go: function (state) {
            var thiz = this;

            switch (state) {
                case "s":
                    if (this.p.speed2 > 1) {
                        this.targetObj.show().css({
                            width: this.p.sa.width - 50,
                            height: this.p.sa.height - 50,
                            left: this.p.sa.left + 25,
                            top: this.p.sa.top + 25,
                            opacity: 0.1
                        }).animate({
                            width: this.p.sa.width + 10,
                            height: this.p.sa.height + 10,
                            left: this.p.sa.left - 5,
                            top: this.p.sa.top - 5,
                            opacity: 0.5
                        }, this.p.speed, function () {
                            thiz.targetObj.animate({
                                width: thiz.p.sa.width,
                                height: thiz.p.sa.height,
                                left: thiz.p.sa.left,
                                top: thiz.p.sa.top,
                                opacity: 1
                            }, thiz.p.speed2, function () {
                                if (FJ.isIE) thiz.targetObj[0].style.filter = "";  //解决IE下设置为透明的层里面的元素也透明的bug
                                thiz.p.cbS.call(thiz);
                            });
                        });
                    }
                    else {
                        this.targetObj.css({
                            width: this.p.sa.width,
                            height: this.p.sa.height,
                            left: this.p.sa.left,
                            top: this.p.sa.top,
                            opacity: this.p.opacity
                        }).fadeIn(this.p.speed, function () {
                            thiz.targetObj.show();
                            thiz.p.cbS.call(thiz);
                        }).show();
                    }
                    break;
                case "c":
                    if (this.p.speed2 > 1) {
                        this.p.cbP.call(this);
                        this.targetObj.animate({
                            width: this.p.sa.width + 10,
                            height: this.p.sa.height + 10,
                            left: this.p.sa.left - 5,
                            top: this.p.sa.top - 5,
                            opacity: 0.5
                        }, thiz.p.speed3, function () {
                            thiz.targetObj.animate({
                                width: (thiz.p.sa.width - 50 >= 0 ? thiz.p.sa.width - 50 : 0),
                                height: (thiz.p.sa.height - 50 >= 0 ? thiz.p.sa.height - 50 : 0),
                                left: thiz.p.sa.left + 25,
                                top: thiz.p.sa.top + 25,
                                opacity: 0.1
                            }, thiz.p.speed, function () {
                                thiz.targetObj.hide();
                                thiz.p.cbC.call(thiz);
                            });
                        });
                    }
                    else {
                        this.targetObj.fadeOut(this.p.speed, function () {
                            thiz.p.cbC.call(thiz);
                        });
                    }
                    break;
            }
        }
        //#endregion
    });
    //#endregion

    //#endregion

    //#region silverlight
    FJ.SilverLight = FJ.SL = function () {
        ///	<summary>
        /// silverlight
        ///	</summary>
    };

    //#region silverlight报错方法
    this.onSLeJ = this.onSilverlightErrorJ = function (sender, args) {
        var appSource = "";
        if (sender != null && sender != 0) {
            appSource = sender.getHost().Source;
        }

        var errorType = args.ErrorType;
        var iErrorCode = args.ErrorCode;

        if (errorType == "ImageError" || errorType == "MediaError") {
            return;
        }

        var errMsg = "Silverlight 应用程序中未处理的错误 " + appSource + "\n";

        errMsg += "代码: " + iErrorCode + "    \n";
        errMsg += "类别: " + errorType + "       \n";
        errMsg += "消息: " + args.ErrorMessage + "     \n";

        if (errorType == "ParserError") {
            errMsg += "文件: " + args.xamlFile + "     \n";
            errMsg += "行: " + args.lineNumber + "     \n";
            errMsg += "位置: " + args.charPosition + "     \n";
        }
        else if (errorType == "RuntimeError") {
            if (args.lineNumber != 0) {
                errMsg += "行: " + args.lineNumber + "     \n";
                errMsg += "位置: " + args.charPosition + "     \n";
            }
            errMsg += "方法名称: " + args.methodName + "     \n";
        }

        throw new Error(errMsg);
    };
    //#endregion

    //#region 检测silverlight播放器是否安装
    FJ.SL.CheckSLInstalled = function () {
        var isSilverlightInstalled = false;
        try {
            try {
                var slControl = new ActiveXObject('AgControl.AgControl'); //检查IE   
                isSilverlightInstalled = true;
            }
            catch (e) {
                if (navigator.plugins["Silverlight Plug-In"]) //检查非IE   
                {
                    isSilverlightInstalled = true;
                }
            }
        }
        catch (e) { }
        return isSilverlightInstalled;
    };
    //#endregion

    //#region 创建silverlight承载标签
    FJ.SL.CreateObj = function (p) {
        var objSlHtml = ['<object id="' + p.id + '" data="data:application/x-silverlight-2," type="application/x-silverlight-2" style="width:100%;height:100%;">'];
        objSlHtml.push('<param name="source" value="' + p.xapPath + '" />');
        objSlHtml.push('<param name="onerror" value="onSLeJ" />');
        objSlHtml.push('<param name="background" value="white" />');
        objSlHtml.push('<param name="onload" value="pluginLoaded" />');
        objSlHtml.push('<param name="minRuntimeVersion" value="4.0.50826.0" />');
        objSlHtml.push('<param name="autoUpgrade" value="true" />');
        objSlHtml.push('<param value="' + p.windowless + '" name="windowless" />');  //使sl不会遮住下拉框等元素
        objSlHtml.push('<param name="initParams" value="'+p.initParams+'" />');
        objSlHtml.push('<a href="http://go.microsoft.com/fwlink/?LinkID=124807" style="text-decoration: none;"><img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="获取 Microsoft Silverlight" style="border-style: none" /></a>');
        objSlHtml.push('</object>');
        objSlHtml.push('<iframe style="visibility: hidden; height: 0; width: 0; border: 0px"></iframe>');
        return objSlHtml.join("");
    };
    //#endregion

    //#endregion

    //#region flex
    FJ.Flex = FJ.FX = function () {
        ///	<summary>
        /// flex
        ///	</summary>
    };
    //#endregion

    //#region 获取网站根目录路径
    FJ.getRootPath = function (rootFolder) {
        if (rootFolder == null) {
            rootFolder = "/Web";
        }
        var strFullPath = window.document.location.href;

        var strPath = window.document.location.pathname;

        var pos = strFullPath.indexOf(strPath);

        var prePath = strFullPath.substring(0, pos);

        var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1);
        if (postPath != rootFolder) {
            postPath = "";
        }
        return (prePath + postPath);
    }
    //#endregion

    //#region 计算当前窗口距离
    //#region 计算当前窗口的上边滚动条
    FJ.topPosition = function () {
        return typeof window.pageYOffset != 'undefined' ? window.pageYOffset : document.documentElement && document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ? document.body.scrollTop : 0;
    }
    //#endregion

    //#region 计算当前窗口的左边滚动条
    FJ.leftPosition = function () {
        return typeof window.pageXOffset != 'undefined' ? window.pageXOffset : document.documentElement && document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ? document.body.scrollLeft : 0;
    }
    //#endregion

    //#region 计算当前窗口的宽度
    FJ.pageWidth = function () {
        return window.innerWidth != null ? window.innerWidth : document.documentElement && document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body != null ? document.body.clientWidth : null;
    }
    //#endregion

    //#region 计算当前窗口的高度
    FJ.pageHeight = function () {
        return window.innerHeight != null ? window.innerHeight : document.documentElement && document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body != null ? document.body.clientHeight : null;
    }
    //#endregion
    //#endregion

    //#region 克隆对象
    FJ.clone = function (myObj) {
        if (typeof (myObj) != 'object') return myObj;
        if (myObj == null) return myObj;

        var myNewObj = new Object();

        for (var i in myObj)
            myNewObj[i] = FJ.clone(myObj[i]);

        return myNewObj;
    }
    //#endregion

    //#region 字符串构造器
    FJ.StringBuilder = FJ.strB = function () {
        this.strings = new Array();
    }

    FJ.strB.prototype.append = FJ.strB.prototype.add = function (str) {
        this.strings[this.strings.length] = str;
    }

    FJ.strB.prototype.toString = FJ.strB.prototype.join = function (sign) {   //sign为分隔符
        if (sign == null) {
            sign = "";
        }
        return this.strings.join(sign);
    }

    FJ.strB.prototype.clear = function () {
        this.strings = [];
    }

    FJ.sb = function () {   //静态方法
        return new FJ.strB();
    }
    //#endregion

    //#region 判断浏览器

    //浏览器名称
    FJ.browserName = navigator.userAgent.toLowerCase();

    //浏览器判断对象
    FJ.browser = {
        version: (FJ.browserName.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [0, '0'])[1],
        safari: /webkit/i.test(FJ.browserName) && !this.chrome,
        opera: /opera/i.test(FJ.browserName),
        firefox: /firefox/i.test(FJ.browserName),
        ie: /msie/i.test(FJ.browserName) && !/opera/.test(FJ.browserName),
        mozilla: /mozilla/i.test(FJ.browserName) && !/(compatible|webkit)/.test(FJ.browserName) && !this.chrome,
        chrome: /chrome/i.test(FJ.browserName) && /webkit/i.test(FJ.browserName) && /mozilla/i.test(FJ.browserName)
    };

    //IE
    FJ.isIE = FJ.browser.ie;

    //IE6
    FJ.isIE6 = FJ.browser.ie && FJ.browser.version == 6.0;

    //IE7
    FJ.isIE7 = FJ.browser.ie && FJ.browser.version == 7.0;

    //IE8
    FJ.isIE8 = FJ.browser.ie && FJ.browser.version == 8.0;

    //IE9
    FJ.isIE9 = FJ.browser.ie && FJ.browser.version == 9.0;

    //IE除了IE9
    FJ.isIEno9 = FJ.isIE6 || FJ.isIE7 || FJ.isIE8;

    //FireFox
    FJ.isFF = FJ.browser.mozilla;

    //FireFox4以上
    FJ.isFF4up = (function () {
        var b = false;
        if (FJ.isFF) {
            if (parseInt(FJ.browserName.substr(FJ.browserName.indexOf("firefox/") + 8, 1)) >= 4)
                b = true;
        }
        return b;
    })();

    //Chrome
    FJ.isChrome = FJ.browser.chrome;

    //Safari
    FJ.isSafari = FJ.browser.safari;

    //Chrome&Safari
    FJ.isWebkit = FJ.isChrome || FJ.isSafari;

    //Opera
    FJ.isOpera = FJ.browser.opera;

    //#endregion

    //#region 判断操作系统

    //XP
    FJ.isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;

    //server 2003
    FJ.isWinS2003 = navigator.userAgent.indexOf("Windows NT 5.2") != -1;

    //vista
    FJ.isWinVista = navigator.userAgent.indexOf("Windows NT 6.0") != -1;

    //win7
    FJ.isWin7 = navigator.userAgent.indexOf("Windows NT 6.1") != -1;

    //#endregion

    //#region 使IE和其他标准浏览器的事件对象统一
    FJ.fixEvent = FJ.fixE = function (e) {
        if (typeof e == 'undefined') e = window.event;
        if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
        if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
        e.key = e.keyCode ? e.keyCode : e.which;    //兼容IE和Firefox获得keyBoardEvent对象的键值
        return e;
    }
    //#endregion

    //#region 在1位数字前补零
    FJ.addZero = function (n) {
        return (("00" + n).substr(("00" + n).length - 2));
    }
    //#endregion

    //#region 原型扩展方法

    //#region 数组
    //插入
    Array.prototype.insertAt = function (index, value) {
        this.splice(index, 0, value);
    };

    //移除
    Array.prototype.removeAt = function (index) {
        this.splice(index, 1);
    }

    //移动
    Array.prototype.moveTo = function (inxOld, inxNew) {
        this.insertAt(inxNew + 1, this[inxOld]);
        this.removeAt(inxOld);
    }
    //#endregion

    //#region 数字
    Number.prototype.NaN0 = function () {
        return isNaN(this) ? 0 : this;
    }

    Number.prototype.toFormatString = function () {
        var _str = '00' + this;
        return _str.substring(_str.length - 2, _str.length);
    }
    //#endregion

    //#region 日期
    Date.prototype.toFormatString = function (fs, noAddZero) {
        if (fs.length == 1) {
            return this.getFullYear() + fs + (this.getMonth() + 1) + fs + this.getDate();
        }
        fs = fs.replace("yyyy", this.getFullYear());
        fs = fs.replace("mm", noAddZero ? (this.getMonth() + 1) : FJ.addZero(this.getMonth() + 1));
        fs = fs.replace("dd", noAddZero ? this.getDate() : FJ.addZero(this.getDate()));
        fs = fs.replace("hh", noAddZero ? this.getHours() : FJ.addZero(this.getHours()));
        fs = fs.replace("MM", noAddZero ? this.getMinutes() : FJ.addZero(this.getMinutes()));
        fs = fs.replace("ss", noAddZero ? this.getSeconds() : FJ.addZero(this.getSeconds()));
        return fs;
    }
    //#endregion

    //#endregion

    //#region 播放声音

    //播放声音对象/*注：如果FF安装了mediawrap插件则能使用bgsound播放*/
    FJ.playSound = FJ.PS = { playNotIE: true };

    //预加载声音
    FJ.playSound.init = function (id, media) {
        if (FJ.isIE) {
            document.write('<bgsound id="fjps_bg_' + id + '" volume="-5000" loop="1" src="' + media + '">');
        }
        else {
            if ((FJ.isWinXP || FJ.isWinVista || FJ.isWin7) && FJ.PS.playNotIE) {
                //document.write('<span id="fjps_sp_' + id + '"><bgsound volume="-1000000" id="fjps_bg_' + id + '" loop="1" src="' + media + '"></span>');
                document.write('<span id="fjps_sp_' + id + '"><embed width="0" height="0" id="fjps_bg_' + id + '" autostart="1" pluginspage="http://www.microsoft.com/windows/windowsmedia/" playcount="1" volume="-9900" mediawrapchecked="true" src="' + media + '" type="application/x-mplayer2" splayername="BG" tplayername="NewWMP"></span>');
            }
        }
    };

    //播放声音
    FJ.playSound.play = function (id, media) {
        if (FJ.isIE) {
            var sound = $("#fjps_bg_" + id)[0];
            sound.volume = 1;
            sound.src = sound.src;
        }
        else {
            if ((FJ.isWinXP || FJ.isWinVista || FJ.isWin7) && FJ.PS.playNotIE) {
                var sound = $("#fjps_sp_" + id)[0];
                //sound.innerHTML = '<bgsound volume="1" id="fjps_bg_' + id + '" loop="1" src="' + $("#fjps_bg_" + id)[0].src + '" />';
                sound.innerHTML = '<embed width="0" height="0" id="fjps_bg_' + id + '" autostart="1" pluginspage="http://www.microsoft.com/windows/windowsmedia/" playcount="1" volume="0" mediawrapchecked="true" src="' + $("#fjps_bg_" + id)[0].src + '" type="application/x-mplayer2" splayername="BG" tplayername="NewWMP">';
            }
        }
    };

    //#endregion

    //#region 获取鼠标在某元素内部的坐标
    FJ.getXY = function (el) {
        ///	<summary>
        /// 获取鼠标在某元素内部的坐标
        ///	</summary>
        var d = document,
			bd = d.body,
			r = { t: 0, l: 0 },
			ua = navigator.userAgent.toLowerCase(),
			isStrict = d.compatMode == "CSS1Compat",
			isGecko = /gecko/.test(ua),
			add = function (t, l) { r.l += l, r.t += t },
			p = el;
        if (el && el != bd) {
            if (el.getBoundingClientRect) {
                var b = el.getBoundingClientRect();
                add(b.top + Math.max(d.body.scrollTop, d.documentElement.scrollTop),
					b.left + Math.max(d.body.scrollLeft, d.documentElement.scrollLeft));
                isStrict ? add(-d.documentElement.clientTop, -d.documentElement.clientLeft) : add(-1, -1)
            } else {
                var dv = d.defaultView;
                while (p) {
                    add(p.offsetTop, p.offsetLeft);
                    var computStyle = dv.getComputedStyle(p, null);
                    if (isGecko) {
                        var bl = parseInt(computStyle.getPropertyValue('border-left-width'), 10) || 0,
							bt = parseInt(computStyle.getPropertyValue('border-top-width'), 10) || 0;
                        add(bt, bl);
                        if (p != el && computStyle.getPropertyValue('overflow') != 'visible')
                            add(bt, bl);
                    }
                    p = p.offsetParent;
                }
                p = el.parentNode;
                while (p && p != bd) {
                    add(-p.scrollTop, -p.scrollLeft);
                    p = p.parentNode;
                }
            }
        }
        return r;
    }
    //#endregion

    //#region 正则表达式
    FJ.RegExp = FJ.RX = {
        test: function (exp, val) {
            if (new RegExp(exp).test(val))
                return true;
            else
                return false;
        },
        ep: {   //常用正则表达式
            num: /^\+?[1-9][0-9]*$/,  //大于0的整数
            numZ: /^\+?[0-9][0-9]*$/, //正整数(包含0)
            numF: /^-?([0-9][0-9]*)(\.\d{1,2})?$/, //数字(包含负数、0,最多两位小数)
            numF2: /^([0-9][0-9]*)(\.\d{1,2})?$/, //数字(不含负数,最多两位小数)
            numD: /^-?([0-9][0-9]*)(\.\d{1,10})?$/, //数字(包含负数、0,最多10位小数)
            numD2: /^(([0-9]+[\.]?[0-9]+)|[1-9])$/, //数字(不含负数和0,无限位小数)
            post: /^\d{6}$/, //邮编
            phone: /^(((\()?\d{2,4}(\))?[-(\s)*]){0,2})?(\d{7,8})$/, //固定电话(区号部分为2-4位数字,外面可以加括号,后面可以加斜杠或空格,可重复1-2次;电话号码部分为7-8位)
            mobile: /^[1][3,5,8][0-9]{9}$/, //手机号
            email: /^[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9}$/, //Email(@前面不能以点为结尾)
            date: /^\d{4}-\d{2}-\d{2}$/,  //日期是否yyyy-MM-dd格式
            time: /^\d{2}:\d{2}:\d{2}$/,  //时间是否hh:mm:ss格式
            pass: /^[0-9a-zA-Z]{6,16}$/,  //密码格式是否由字母和数字组成,长度为6-16位
            user: /^[a-zA-Z][a-zA-Z0-9_\u4E00-\u9FA5]{3,15}$/,  //用户名格式是否由字母、数字、中文和下划线组成,以字母开头,长度为4-16位
            ip: /^((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d)(\.((25[0-5])|(2[0-4]\d)|(1\d\d)|([1-9]\d)|\d)){3}(:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}))?$/, //IP格式为xxx.xxx.xxx.xxx或xxx.xxx.xxx.xxx:端口号,xxx的值必须是0-255,端口号的值必须是1-65535
            cardId: /^(\d{18,18}|\d{15,15}|\d{17,17}x)$/i   //身份证
        }
    };

    for (var ep in FJ.RegExp.ep) {   //测试表达式方法
        (function (o) {
            FJ.RegExp[o] = function (val) {
                return FJ.RX.test(FJ.RX.ep[o], val);
            };
        })(ep);
    }
    //#endregion

    //#region 日期
    FJ.Date = {};

    //日期转换
    FJ.Date.parse = function (s) {
        var d = new Date(s.replace(/-/g, "/").replace(/T/g, " "));
        return d;
    }

    //日期比较
    FJ.Date.dateDiff = function (sDate1, sDate2, useAbs) {
        var aDate, oDate1, oDate2, iDays;
        aDate = sDate1.split('-');
        oDate1 = new Date(aDate[1] + '/' + aDate[2] + '/' + aDate[0]);
        //转换为04-19-2007格式 
        aDate = sDate2.split('-');
        oDate2 = new Date(aDate[1] + '/' + aDate[2] + '/' + aDate[0]);
        var diff = 0;
        if (useAbs)
            days = Math.abs(oDate1 - oDate2);
        else
            days = oDate1 - oDate2;
        iDays = parseInt(days / 1000 / 60 / 60 / 24); //把相差的毫秒数转换为天数 
        return iDays;
    },
    //#endregion

    //#region 请求对象
    FJ.Request = {};

    FJ.Request.queryString = FJ.Request.qs = function (item) {
        var svalue = location.search.match(new RegExp("[\?\&]" + item + "=([^\&]*)(\&?)", "i"));
        return svalue ? svalue[1] : svalue;
    }
    //#endregion

})(jQuery);